package com.yiyahui.framework.config;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.yiyahui.framework.aspectj.lang.annotation.Desensitized;
import com.yiyahui.framework.aspectj.lang.enums.SensitiveTypeEnum;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SensitiveInfoSerializer extends JsonSerializer<String> implements ContextualSerializer {
    private Logger logger = LoggerFactory.getLogger(SensitiveInfoSerializer.class);
    private SensitiveTypeEnum type;

    public SensitiveInfoSerializer() {
    }

    public SensitiveInfoSerializer(final SensitiveTypeEnum type) {
        this.type = type;
    }

    @Override
    public void serialize(final String s, final JsonGenerator jsonGenerator,
            final SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
        //Desensitized desensitization;
        List<String> regular;
        /*switch (type) {
            case CUSTOM:
                regular = Arrays.asList(desensitization.attach());
                break;
            case TRUNCATE:
                regular = truncateRender(desensitization.attach());
                break;
            default:
                regular = Arrays.asList(type.getRegular());
        }*/
        regular = Arrays.asList(type.getRegular());
        if (regular.size() > 1) {
            String match = regular.get(0);
            String result = regular.get(1);
            if (null != match && result != null && match.length() > 0) {
                jsonGenerator.writeString(s.replaceAll(match, result));
            }
        }
    }

    @Override
    public JsonSerializer<?> createContextual(final SerializerProvider serializerProvider,
            final BeanProperty beanProperty) throws JsonMappingException {
        if (beanProperty != null) { // 为空直接跳过
            if (Objects.equals(beanProperty.getType().getRawClass(), String.class)) { // 非 String 类直接跳过
                Desensitized desensitized = beanProperty.getAnnotation(Desensitized.class);
                if (desensitized == null) {
                    desensitized = beanProperty.getContextAnnotation(Desensitized.class);
                }
                if (desensitized != null) { // 如果能得到注解，就将注解的 value 传入 SensitiveInfoSerialize

                    return new SensitiveInfoSerializer(desensitized.type());
                }
            }
            return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
        }
        return serializerProvider.findNullValueSerializer(beanProperty);
    }

    private List<String> truncateRender(String[] attachs) {
        List<String> regular = new ArrayList<>();
        if (null != attachs && attachs.length >1) {
            String rule = attachs[0];
            String size = attachs[1];
            String template, result;
            if ("0".equals(rule)) {
                template = "^(\\S{%s})(\\S+)$";
                result = "$1";
            } else if ("1".equals(rule)) {
                template = "^(\\S+)(\\S{%s})$";
                result = "$2";
            } else {
                return regular;
            }
            try {
                if (Integer.parseInt(size) > 0) {
                    regular.add(0, String.format(template, size));
                    regular.add(1, result);
                }
            } catch (Exception e) {
                logger.warn("ValueDesensitizeFilter truncateRender size {} exception", size);
            }
        }
        return regular;
    }
}